#pragma once


#include <stdint.h>

#include <tuple>


namespace calc {

    /**
     * @brief 将计数按单位四舍五入到最接近的倍数，等效于round((float)(count) / unit)
     *
     * 此函数将一个计数值按照给定的单位进行四舍五入，返回最接近的单位倍数。
     * 例如: count=150, unit=100 → 返回2 (表示2个100单位)
     *
     * @param count 需要四舍五入的计数值
     * @param unit 四舍五入的单位（必须大于0）
     * @return uint32_t 四舍五入后的单位倍数
     *
     * @note 如果unit为0或1，函数直接返回count，因为不需要四舍五入
     */
    template <typename T>
    constexpr T round_by_unit(T count, uint16_t unit) {
        // 处理无效或不需要四舍五入的情况
        if (unit <= 1) {
            return count;
        }

        // 标准四舍五入算法: (count + unit/2) / unit
        return (count + unit / 2) / unit;
    }


    constexpr uint32_t pack_u32(uint32_t h, uint32_t l) {
        uint32_t r = (h << 16) + l;
        return r;
    }


    constexpr uint32_t pack_u32(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
        uint32_t r = (a << 24) + (b << 16) + (c << 8) + d;
        return r;
    }


    constexpr uint16_t pack_u16(uint16_t h, uint16_t l) {
        uint16_t r = (h << 8) + l;
        return r;
    }


    constexpr std::tuple<uint16_t, uint16_t> split_u32_to_u16(uint32_t v) {
        return {static_cast<uint16_t>(v >> 16), static_cast<uint16_t>(v)};
    }


    constexpr std::tuple<uint8_t, uint8_t> split_u16_to_u8(uint16_t v) {
        return {static_cast<uint8_t>(v >> 8), static_cast<uint8_t>(v)};
    }

}  // namespace calc